#ifndef AV_FRAME_BUF_H
#define AV_FRAME_BUF_H
#include "av_pkt_buf.h"

typedef struct av_frame_buf_s av_frame_buf_t;
typedef struct av_frame_buf_manager_s av_frame_buf_manager_t;

typedef enum av_frame_buf_type_e {
    AV_FRAME_BUF_TYPE_GENERIC,
    AV_FRAME_BUF_TYPE_MAX,
} av_frame_buf_type_t;

typedef enum av_frame_type_e {
    AV_FRAME_TYPE_I,
    AV_FRAME_TYPE_P,
    AV_FRAME_TYPE_MAX,
} av_frame_type_t;

struct av_frame_buf_s {
    av_frame_buf_type_t buf_type;
    av_frame_type_t type;
    char *data;
    size_t data_len;
    av_frame_buf_manager_t *m;
};

typedef struct av_frame_buf_desc_s av_frame_buf_desc_t;

struct av_frame_buf_manager_s {
    av_frame_buf_desc_t *desc;
    void *priv;
};

typedef av_frame_buf_manager_t *(*av_frame_alloc_manager_func_t)(
    av_frame_buf_desc_t *d);

typedef av_frame_buf_t *(*av_frame_buf_alloc_func_t)(av_frame_buf_manager_t *m);
typedef void (*av_frame_buf_free_func_t)(av_frame_buf_t *buf);
typedef void (*av_frame_buf_reset_func_t)(av_frame_buf_t *buf);
typedef int (*av_frame_buf_add_data_func_t)(av_frame_buf_t *frm_buf,
                                            av_pkt_buf_t *buf);
typedef char *(*av_frame_buf_data_func_t)(av_frame_buf_t *buf);
typedef size_t (*av_frame_buf_data_len_func_t)(av_frame_buf_t *buf);
typedef av_frame_type_t (*av_frame_buf_type_func_t)(av_frame_buf_t *buf);
typedef int (*av_frame_buf_is_keyframe_func_t)(av_frame_buf_t *buf);

struct av_frame_buf_desc_s {
    av_frame_buf_type_t type;
    size_t max_frame_len;
    size_t priv_size;
    size_t priv_hdr_len;

    av_frame_alloc_manager_func_t alloc_manager_func;
    av_frame_buf_alloc_func_t alloc_func;
    av_frame_buf_free_func_t free_func;
    av_frame_buf_reset_func_t reset_func;
    av_frame_buf_add_data_func_t add_data_func;
    av_frame_buf_data_func_t data_func;
    av_frame_buf_data_len_func_t data_len_func;
    av_frame_buf_type_func_t type_func;
    av_frame_buf_is_keyframe_func_t is_keyframe_func;
};

av_frame_buf_manager_t *av_frame_buf_alloc_manager(av_frame_buf_type_t t);

av_frame_buf_t *av_frame_buf_alloc(av_frame_buf_manager_t *m);
void av_frame_buf_free(av_frame_buf_t *buf);
void av_frame_buf_reset(av_frame_buf_t *buf);
int av_frame_buf_add_data(av_frame_buf_t *buf, av_pkt_buf_t *pkt);
char *av_frame_buf_data(av_frame_buf_t *buf);
size_t av_frame_buf_data_len(av_frame_buf_t *buf);
av_frame_type_t av_frame_buf_type(av_frame_buf_t *buf);
int av_frame_buf_is_keyframe(av_frame_buf_t *buf);
#endif /* ifndef AV_FRAME_BUF_H */
